﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agile.Engine.Data;
using Agile.Engine.Utils;

namespace Fis.Web.Rules.Book
{
    public class AccountTreatRule : DynamicRule
    {
        public override void ExecuteNonTrans()
        {
            var action = Paramater["Action"].ToString();
            switch (action)
            {
                case "初始化提交":
                    InitializeSubmit();
                    break;
                case "反初始化提交":
                    ReverseInitializeSubmit();
                    break;
                case "结转损益提交":
                    TransferProfitSubmit();
                    break;
                case "期末调汇提交":
                    AdjustRateSubmit();
                    break;
                case "凭证审核提交":
                    UpdateBillState();
                    break;
                case "凭证反审核提交":
                    UpdateBillState();
                    break;
                case "凭证过账提交":
                    UpdateBillState();
                    break;
                case "凭证反过账提交":
                    UpdateBillState();
                    break;
                case "结账信息提交":
                    AccountSettleSubmit();
                    break;
                case "反结账信息提交":
                    ReverseAccountSettleSubmit();
                    break;
                case "同步凭证号":
                    SyncBillNO();
                    break;
            }
            Status = 1;
        }

        public int BillSequnce(string range)
        {
            var da = new DataAccess() { Context = Model.DataContext, TableName = "TBILLMASTER" };
            return da.Scalar(0, "MAX(FNO)", string.Format("DATEPART(month, FENTERDATE) = {0}", range)) + 1;
        }

        #region //结转损益提交

        void TransferProfitSubmit()
        {
            var BillMasterTB = Model.QueryTable(System.Data.CommandType.Text, "TBILLMASTER", "select * from TBILLMASTER where 1=2");
            var BillDetailTB = Model.QueryTable(System.Data.CommandType.Text, "TBILLDETAIL", "select * from TBILLDETAIL where 1=2");
            var MasterRow = (System.Data.DataRow)null;
            var DetailRow = (System.Data.DataRow)null;
            var MasterSID = (string)null;
            if (int.Parse(Paramater["TransferProfitDebitCount"].ToString()) != 0)
            {
                System.Data.DataTable TransferProfitDebit = ZipUtils.UnZipDataTable(Paramater["TransferProfitDebit"].ToString());
                MasterSID = Guid.NewGuid().ToString();
                var sequnce = 0;
                var hashcode = MasterSID.GetHashCode();
                for (int m = 0; m < TransferProfitDebit.Rows.Count; m++)
                {
                    DetailRow = BillDetailTB.NewRow();
                    DetailRow["SID"] = string.Format("{0}-{1:0000#}", hashcode, ++sequnce);
                    DetailRow["FVCHID"] = MasterSID;
                    DetailRow["FEXPLANATION"] = TransferProfitDebit.Rows[m]["FEXPLANATION"];
                    DetailRow["FACCOUNTCODE"] = TransferProfitDebit.Rows[m]["FACCOUNTCODE"];
                    DetailRow["FDEBITAMOUNT"] = TransferProfitDebit.Rows[m]["FDEBITAMOUNT"];
                    DetailRow["FCREDITAMOUNT"] = TransferProfitDebit.Rows[m]["FCREDITAMOUNT"];
                    DetailRow["FCURRENCYDEBIT"] = TransferProfitDebit.Rows[m]["FCURRENCYDEBIT"];
                    DetailRow["FCURRENCYCREDIT"] = TransferProfitDebit.Rows[m]["FCURRENCYCREDIT"];
                    DetailRow["FRATE"] = TransferProfitDebit.Rows[m]["FRATE"];
                    DetailRow["FQUANTITYDEBIT"] = TransferProfitDebit.Rows[m]["FQUANTITYDEBIT"];
                    DetailRow["FQUANTITYCREDIT"] = TransferProfitDebit.Rows[m]["FQUANTITYCREDIT"];
                    DetailRow["FUNITPRICE"] = TransferProfitDebit.Rows[m]["FUNITPRICE"];
                    DetailRow["FHSVALUE"] = TransferProfitDebit.Rows[m]["FHSVALUE"];
                    DetailRow["SINDEXDATE"] = DateTime.Now;
                    DetailRow["SBOOKID"] = BookID;
                    BillDetailTB.Rows.Add(DetailRow);
                }
                MasterRow = BillMasterTB.NewRow();
                MasterRow["SID"] = MasterSID;
                MasterRow["FBILLTYPE"] = Paramater["BillType"];
                MasterRow["FNO"] = BillSequnce(BookRange);
                MasterRow["FATTACHMENT"] = 0;
                MasterRow["FREMARK"] = null;
                MasterRow["FENTERDATE"] = string.Format("{0}-{1}-{2} 00:00:00", Paramater["Year"], Paramater["Range"], System.DateTime.Now.Day);
                MasterRow["FENTER"] = Paramater["UserSID"];
                //MasterRow["FCHECKED"] = Paramater["UserSID"];
                //MasterRow["FPOST"] = Paramater["UserSID"];
                MasterRow["FSTATUS"] = 0;
                MasterRow["FSORT"] = 2;
                MasterRow["FSORTID"] = 0;
                MasterRow["FSEQUENCE"] = MasterRow["FNO"];
                MasterRow["FSYNC"] = 1;
                MasterRow["SINDEXDATE"] = DateTime.Now;
                MasterRow["SBOOKID"] = BookID;
                BillMasterTB.Rows.Add(MasterRow);
            }
            if (int.Parse(Paramater["TransferProfitCreditCount"].ToString()) != 0)
            {
                System.Data.DataTable TransferProfitCredit = ZipUtils.UnZipDataTable(Paramater["TransferProfitCredit"].ToString());
                MasterSID = Guid.NewGuid().ToString();
                var sequnce = 0;
                var hashcode = MasterSID.GetHashCode();

                for (int n = 0; n < TransferProfitCredit.Rows.Count; n++)
                {
                    DetailRow = BillDetailTB.NewRow();
                    DetailRow["SID"] = string.Format("{0}-{1:0000#}", hashcode, ++sequnce);

                    DetailRow["FVCHID"] = MasterSID;
                    DetailRow["FEXPLANATION"] = TransferProfitCredit.Rows[n]["FEXPLANATION"];
                    DetailRow["FACCOUNTCODE"] = TransferProfitCredit.Rows[n]["FACCOUNTCODE"];
                    DetailRow["FDEBITAMOUNT"] = TransferProfitCredit.Rows[n]["FDEBITAMOUNT"];
                    DetailRow["FCREDITAMOUNT"] = TransferProfitCredit.Rows[n]["FCREDITAMOUNT"];
                    DetailRow["FCURRENCYDEBIT"] = TransferProfitCredit.Rows[n]["FCURRENCYDEBIT"];
                    DetailRow["FCURRENCYCREDIT"] = TransferProfitCredit.Rows[n]["FCURRENCYCREDIT"];
                    DetailRow["FRATE"] = TransferProfitCredit.Rows[n]["FRATE"];
                    DetailRow["FQUANTITYDEBIT"] = TransferProfitCredit.Rows[n]["FQUANTITYDEBIT"];
                    DetailRow["FQUANTITYCREDIT"] = TransferProfitCredit.Rows[n]["FQUANTITYCREDIT"];
                    DetailRow["FUNITPRICE"] = TransferProfitCredit.Rows[n]["FUNITPRICE"];
                    DetailRow["FHSVALUE"] = TransferProfitCredit.Rows[n]["FHSVALUE"];
                    DetailRow["SINDEXDATE"] = DateTime.Now;
                    DetailRow["SBOOKID"] = BookID;
                    BillDetailTB.Rows.Add(DetailRow);
                }
                MasterRow = BillMasterTB.NewRow();
                MasterRow["SID"] = MasterSID;
                MasterRow["FBILLTYPE"] = Paramater["BillType"];
                MasterRow["FNO"] = BillSequnce(BookRange) + 1;
                MasterRow["FATTACHMENT"] = 0;
                MasterRow["FREMARK"] = null;
                MasterRow["FENTERDATE"] = string.Format("{0}-{1}-{2} 00:00:00", Paramater["Year"], Paramater["Range"], System.DateTime.Now.Day);
                MasterRow["FENTER"] = Paramater["UserSID"];
                //MasterRow["FCHECKED"] = Paramater["UserSID"];
                //MasterRow["FPOST"] = Paramater["UserSID"];
                MasterRow["FSTATUS"] = 0;
                MasterRow["FSORT"] = 2;
                MasterRow["FSORTID"] = 0;
                MasterRow["FSEQUENCE"] = MasterRow["FNO"];
                MasterRow["FSYNC"] = 1;
                MasterRow["SINDEXDATE"] = DateTime.Now;
                MasterRow["SBOOKID"] = BookID;
                BillMasterTB.Rows.Add(MasterRow);
            }
            DataAccess a = new DataAccess() { Context = Model.DataContext, TableName = "TBILLMASTER" };
            a.AddNew(BillMasterTB.Select());
            DataAccess b = new DataAccess() { Context = Model.DataContext, TableName = "TBILLDETAIL" };
            b.AddNew(BillDetailTB.Select());
            Result["BillMasterTB"] = ZipUtils.ZipDataTable(BillMasterTB);
            Result["BillDetailTB"] = ZipUtils.ZipDataTable(BillDetailTB);
        }

        #endregion

        #region //期末调汇

        void AdjustRateSubmit()
        {
            var BillMasterTB = Model.QueryTable(System.Data.CommandType.Text, "TBILLMASTER", "select * from TBILLMASTER where 1=2");
            var MasterRow = (System.Data.DataRow)null;
            var MasterSID = (string)null;
            System.Data.DataTable BillDetailTB = (System.Data.DataTable)null;
            if (int.Parse(Paramater["AdjustRateDetailCount"].ToString()) != 0)
            {
                BillDetailTB = ZipUtils.UnZipDataTable(Paramater["AdjustRateDetailTB"].ToString());
                MasterSID = Guid.NewGuid().ToString();
                var sequnce = 0;
                var hashcode = MasterSID.GetHashCode();
                for (int i = 0; i < BillDetailTB.Rows.Count; i++)
                {
                    BillDetailTB.Rows[i]["SID"] = string.Format("{0}-{1:0000#}", hashcode, ++sequnce); 
                    BillDetailTB.Rows[i]["FVCHID"] = MasterSID;
                    BillDetailTB.Rows[i]["SINDEXDATE"] = DateTime.Now;
                    BillDetailTB.Rows[i]["SBOOKID"] = BookID;
                }
                MasterRow = BillMasterTB.NewRow();
                MasterRow["SID"] = MasterSID;
                MasterRow["FBILLTYPE"] = Paramater["BillType"];
                MasterRow["FNO"] = BillSequnce(BookRange);
                MasterRow["FATTACHMENT"] = 0;
                MasterRow["FREMARK"] = null;
                MasterRow["FENTERDATE"] = string.Format("{0}-{1}-{2} 00:00:00", Paramater["Year"], Paramater["Range"], System.DateTime.Now.Day);
                MasterRow["FENTER"] = Paramater["UserSID"];
                //MasterRow["FCHECKED"] = Paramater["UserSID"];
                //MasterRow["FPOST"] = Paramater["UserSID"];
                MasterRow["FSTATUS"] = 0;
                MasterRow["FSORT"] = 3;
                MasterRow["FSORTID"] = 0;
                MasterRow["FSEQUENCE"] = MasterRow["FNO"];
                MasterRow["FSYNC"] = 1;
                MasterRow["SINDEXDATE"] = DateTime.Now;
                MasterRow["SBOOKID"] = BookID;
                BillMasterTB.Rows.Add(MasterRow);
            }
            DataAccess a = new DataAccess() { Context = Model.DataContext, TableName = "TBILLMASTER" };
            a.AddNew(BillMasterTB.Select());
            DataAccess b = new DataAccess() { Context = Model.DataContext, TableName = "TBILLDETAIL" };
            b.AddNew(BillDetailTB.Select());
            Result["BillMasterTB"] = ZipUtils.ZipDataTable(BillMasterTB);
            Result["BillDetailTB"] = ZipUtils.ZipDataTable(BillDetailTB);
        }

        #endregion

        #region //初始化提交

        void InitializeSubmit()
        {
            WebContext.LockBook(BookID, BookState.Init, () =>
            {
                if (int.Parse(Paramater["RestCount"].ToString()) != 0)
                {
                    System.Data.DataTable RestTB = ZipUtils.UnZipDataTable(Paramater["RestTB"].ToString());
                    Model.Delete("TREST", "2=2");
                    for (int i = 0; i < RestTB.Rows.Count; i++)
                    {
                        RestTB.Rows[i]["SID"] = Guid.NewGuid().ToString();
                        RestTB.Rows[i]["SINDEXDATE"] = DateTime.Now;
                        RestTB.Rows[i]["SBOOKID"] = BookID;
                    }
                    DataAccess a = new DataAccess() { Context = Model.DataContext, TableName = "TREST" };
                    a.AddNew(RestTB.Select());
                    Result["RestTB"] = ZipUtils.ZipDataTable(RestTB);
                }
                Result["BOOKSINDEXDATE"] = DateTime.Now;
                if (Paramater["Range"].ToString().Equals("0"))
                    Paramater["Range"] = "1";
                Model.ExecuteNonQuery(string.Format("UPDATE TBOOK SET FBOOKINITIALIZED=1,FBOOKRANGE={0},SINDEXDATE='{1}'", Paramater["Range"], Result["BOOKSINDEXDATE"]));
            });

        }

        void ReverseInitializeSubmit()
        {
            WebContext.LockBook(BookID, BookState.UnInit, () =>
                {
                    Model.Delete("TREST", "2=2");
                    Result["BOOKSINDEXDATE"] = DateTime.Now;
                    Model.ExecuteNonQuery(string.Format("UPDATE TBOOK SET FBOOKINITIALIZED=0,FBOOKRANGE={0},SINDEXDATE='{1}'",
                        Paramater["InitializeRange"], Result["BOOKSINDEXDATE"]));
                    CommonRule rule = new CommonRule();
                    rule.UpdateDeleteInfo(Model.DataContext, "UNREST", "0", BookID, 2);
                });
        }

        #endregion

        #region //凭证状态修改

        void UpdateBillState()
        {
            var action = Paramater["Action"].ToString();
            var sql = (string)null;
            switch (action)
            {
                case "凭证审核提交":
                    sql = "UPDATE TBILLMASTER SET FSTATUS=1,FCHECKED='{0}',SINDEXDATE=GETDATE() where SID in ({1})";
                    Model.ExecuteNonQuery(string.Format(sql, Paramater["FCHECKED"], Paramater["BillMasterSID"]));
                    break;
                case "凭证反审核提交":
                    sql = "UPDATE TBILLMASTER SET FSTATUS=0,FCHECKED= null,SINDEXDATE=GETDATE() where SID in ({0})";
                    Model.ExecuteNonQuery(string.Format(sql, Paramater["BillMasterSID"]));
                    break;
                case "凭证过账提交":
                    sql = "UPDATE TBILLMASTER SET FSTATUS=2,FPOST='{0}',SINDEXDATE=GETDATE() where SID in ({1})";
                    Model.ExecuteNonQuery(string.Format(sql, Paramater["FPOST"], Paramater["BillMasterSID"]));
                    break;
                case "凭证反过账提交":
                    sql = "UPDATE TBILLMASTER SET FSTATUS=1,FPOST= null,SINDEXDATE=GETDATE() where SID in ({0})";
                    Model.ExecuteNonQuery(string.Format(sql, Paramater["BillMasterSID"]));
                    break;
            }
            sql = string.Format("select * from TBILLMASTER where SID in ({0})", Paramater["BillMasterSID"]);
            var NewBillMasterTB = Model.QueryTable(System.Data.CommandType.Text, "TBILLMASTER", sql);
            Result["NewBillMasterTB"] = ZipUtils.ZipDataTable(NewBillMasterTB);
        }

        #endregion

        #region //结账

        void AccountSettleSubmit()
        {
            WebContext.LockBook(BookID, BookState.Close, () =>
                {

                    System.Data.DataTable RestTB = ZipUtils.UnZipDataTable(Paramater["RestTB"].ToString());
                    for (int i = 0; i < RestTB.Rows.Count; i++)
                    {
                        RestTB.Rows[i]["SID"] = Guid.NewGuid().ToString();
                        RestTB.Rows[i]["SINDEXDATE"] = DateTime.Now;
                        RestTB.Rows[i]["SBOOKID"] = BookID;
                    }
                    Model.Delete("TREST", string.Format("2=2 and FRANGE='{0}'", Paramater["Range"].ToString()));
                    DataAccess a = new DataAccess() { Context = Model.DataContext, TableName = "TREST" };
                    a.AddNew(RestTB.Select());
                    Result["RestTB"] = ZipUtils.ZipDataTable(RestTB);
                    Result["BOOKSINDEXDATE"] = DateTime.Now;
                    Model.ExecuteNonQuery(string.Format("UPDATE TBOOK SET FBOOKINITIALIZED=1,FBOOKRANGE={0},SINDEXDATE='{1}'", int.Parse(Paramater["Range"].ToString()) + 1, Result["BOOKSINDEXDATE"]));
                    Backup();
                });
        }

        void ReverseAccountSettleSubmit()
        {
            WebContext.LockBook(BookID, BookState.Close, () =>
               {

                   Model.Delete("TREST", string.Format("2=2 and FRANGE='{0}'", int.Parse(Paramater["Range"].ToString()) - 1));
                   Result["BOOKSINDEXDATE"] = DateTime.Now;
                   Model.ExecuteNonQuery(string.Format("UPDATE TBOOK SET FBOOKINITIALIZED=1,FBOOKRANGE={0},SINDEXDATE='{1}'", int.Parse(Paramater["Range"].ToString()) - 1, Result["BOOKSINDEXDATE"]));
                   Backup();
                   CommonRule rule = new CommonRule();
                   rule.UpdateDeleteInfo(Model.DataContext, "UNREST", Paramater["Range"].ToString(), BookID, 2);
               });
        }

        #endregion

        void Backup()
        {
            var Account=Model.QueryTable("TBOOK").Rows[0]["SID"].ToString();
            var Target = Agile.Engine.Data.DataContext.Get("BaseDataContext").GetConnString + "AutoBackup\\" + Account;
            var SourceFolder = Agile.Engine.Data.DataContext.Get("BaseDataContext").GetConnString + "Books\\" + Account;
            var TargetFolder = string.Format("{0}\\{1}\\", Target, DateTime.Now.ToString("yyyy.MM.dd.HH.mm.ss"));
            var a = (string)null;
            if (!System.IO.Directory.Exists(TargetFolder))
            {
                Agile.Engine.Utils.IOUtils.CreateDirectory(TargetFolder);
            }
            if (System.IO.Directory.Exists(SourceFolder))
            {
                foreach (string _D in System.IO.Directory.GetFileSystemEntries(SourceFolder))
                {
                    System.IO.FileInfo _Fi = new System.IO.FileInfo(_D);
                    _Fi.CopyTo(TargetFolder + _D.Substring(_D.LastIndexOf("\\") + 1), true);
                }
            }
        }

        void SyncBillNO()
        {
            System.Data.DataTable BillMasterTB = ZipUtils.UnZipDataTable(Paramater["BillMasterTB"].ToString());
            for (int i = 0; i < BillMasterTB.Rows.Count; i++)
            {
                BillMasterTB.Rows[i]["FNO"] = i + 1;
                BillMasterTB.Rows[i]["SINDEXDATE"] = DateTime.Now;
                BillMasterTB.Rows[i]["SBOOKID"] = BookID;
            }
            DataAccess a = new DataAccess() { Context = Model.DataContext, TableName = "TBILLMASTER" };
            a.Update(BillMasterTB.Select());
            Result["NewBillMasterTB"] = ZipUtils.ZipDataTable(BillMasterTB);
        }
    }
}
